home *** CD-ROM | disk | FTP | other *** search
- /*
- * astrec.c receive file routines for ATARI ST kermit
- */
-
- #include <osbind.h>
- #include <stdio.h>
- #include "astobj.h"
- #include "astinc.h"
-
- extern FILE *fopen(),*fopenb();
-
- /*
- * r e c s w
- *
- * This is the state table switcher for receiving files.
- */
-
- recsw()
- {
- char rinit(), rfile(), rdata(); /* Use these procedures */
- start_timer(&starttrans);
- state = 'R';
- n = 0; /* Initialize message number */
- numtry = 0; /* Say no tries yet */
-
- /*
- * We are commenting out code that automatically NAKed
- * in case the sender started first; this may be the reason
- * that this Kermit gets out of whack. The original code
- * said
- * if (gflg == FALSE)
- * spack('N', n, 0, NIL);
- */
-
- for (;;) {
- msgdeb(MSGDSTAT,state,n);
- bps = ((timer(starttrans) != 0) ?
- (bytecnt/timer(starttrans)) : 0);
- dt_packets(TRUE);
- switch(state) { /* Do until done */
- case 'R':
- state = rinit(); break; /* Receive-Init */
- case 'F':
- state = rfile(); break; /* Receive-File */
- case 'D':
- state = rdata(); break; /* Receive-Data */
- case 'C':
- return(TRUE); /* Complete state */
- case 'A':
- spack('E', n, 5, "Abort");
- return (FALSE); /* "Abort" */
- case 'E':
- return(FALSE); /* "Error Abort" */
- default:
- msgdeb(MSGSTATE);
- return (FALSE); /* Unknown, fail */
- }
- }
- }
-
- /*
- * r i n i t
- *
- * Receive Initialization
- */
-
- char rinit()
- {
- int i, len, num; /* Packet length, number */
- char sfile(); /* routine used for get command */
-
- if (numtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER); return('A');};
-
- ebq = TRUE; /* assume 7-bit transfer for init */
- switch(rpack(&len, &num, packet)) { /* Get a packet */
- case 'S': /* Send-Init */
- for (i=len;i<10;i++) packet[i] = '\0';
- rpar(packet); /* Get the other side's init data */
- spar(packet); /* Fill up packet with my init info */
- spack('Y', n, 7, packet); /* ACK with my parameters */
- oldtry = numtry; /* Save old try count */
- numtry = 0; /* Start a new counter */
- n = (n + 1) % 64; /* Bump packet number, mod 64 */
- n_total++;
- return('F'); /* Enter File-Receive state */
-
- case 'E': /* Error packet received */
- prerrpkt(packet); /* Print it out and */
- return('E'); /* abort */
-
- case FALSE: /* Didn't get packet */
- case 'N': /* or got a NAK */
- nakcnt++;
- if (!getfile)
- spack('N', n, 0, NIL); /* Return a NAK */
- else
- spack('R',n,strlen(filnam1),filnam1);
- return(state); /* Keep trying */
-
- case 'Y':
- return(state); /* Ignore leftover ACK */
- /* (or incorrect ACK of 'R' packet) */
-
- case 'A':
- return('A'); /* user abort */
-
- default:
- msgall(KRPROERR,MSGPROER);
- return('A'); /* Some other packet type, "abort" */
- }
- }
-
- /*
- * r f i l e
- *
- * Receive File Header
- */
-
- char rfile()
- {
- int num, len; /* Packet number, length */
- int f1x, fx; /* index to filnam1 and filnam */
- int extx; /* start of extension */
- int tryix; /* trying numbers for extension */
- char convc; /* converted char in filename */
-
- if (numtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER); return('A');};
-
- switch (rpack(&len, &num, packet)) { /* Get a packet */
- case 'S': /* Send-Init, maybe our ACK lost */
- nakcnt++;
- if (oldtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER); return('A');};
- if (num != ((n == 0) ? 63 : n - 1))
- {msgall(KRPROERR,MSGPROER);
- return('A'); /* Not previous packet, "abort" */
- };
- /* Previous packet, mod 64; ack with our */
- /* Send-Init parameters */
- spar(packet);
- spack('Y', num, 7, packet);
- numtry = 0; /* Reset try counter */
- return(state); /* Stay in this state */
-
- case 'Z': /* End-Of-File */
- nakcnt++;
- if (oldtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER); return('A');};
- if (num != ((n==0) ? 63:n-1))
- {msgall(KRPROERR,MSGPROER);
- return('A'); /* Not previous packet, "abort" */
- };
- spack('Y',num,0,NIL);
- numtry = 0;
- return(state); /* Stay in this state */
-
- case 'F': /* File Header (just what we want) */
- if (num != n)
- {msgall(KRPROERR,MSGPROER);
- return('A'); /* The packet number must be right */
- };
- strcpy(filnam1, packet); /* Copy the file name */
-
- /* convert filename to valid TOS file name*/
- fx = 0;
- extx = -1;
- if (filnam[0] == '\0')
- {for (f1x = 0; filnam1[f1x] != '\0'; f1x++)
- {convc = filnam1[f1x];
- if ((convc >= 'a') && (convc <= 'z'))
- convc ^= 040;
- if (convc == ' ')
- convc = '.';
- if (!((convc == '.') ||
- ((convc >= 'A') && (convc <= 'Z')) ||
- ((convc >= '0') && (convc <= '9'))))
- convc = ']';
- if (convc == '.')
- if (extx >= 0)
- convc = ']';
- else
- extx = fx;
- if ((fx < 8) ||
- ((extx >= 0) &&
- ((fx - extx) < 4)))
- filnam[fx++] = convc;
- };
- filnam[fx] = '\0';
- if (filnamwarn)
- {tryix = 0;
- while ((!access(filnam,4)) && (tryix < 50))
- {msgdeb(MSGERSNA,filnam1,filnam);
- if (extx < 0)
- {extx = fx;
- filnam[fx++] = '.';
- filnam[fx] = '\0';
- };
- sprintf(&filnam[extx+1],"K%02d",tryix++);
- };
- };
- };
-
- /* Try to open a new file */
-
- if (image)
- fp = fopenb(filnam,"w");
- else
- fp = fopen(filnam,"w");
- if (fp == NULL) {
- msgall(KRWOPERR,MSGWOPER, filnam);
- return('A'); /* Give up */
- }
-
- /* OK, give message */
- msgall(-1,MSGFRASF, filnam1, filnam);
- dt_files(TRUE);
- spack('Y', n, 0, NIL); /* Acknowledge the file header */
- n_total++;
- oldtry = numtry; /* Reset try counters */
- numtry = 0; /* ... */
- n = (n + 1) % 64; /* Bump packet number, mod 64 */
- return('D'); /* Switch to Data state */
-
- case 'B': /* Break transmission (EOT) */
- if (num != n)
- {msgall(KRPROERR,MSGPROER);
- return ('A'); /* Need right packet number here */
- };
- spack('Y', n, 0, NIL); /* Say OK */
- n_total++;
- return('C'); /* Go to complete state */
-
- case 'E': /* Error packet received */
- prerrpkt(packet); /* Print it out and */
- return('E'); /* abort */
-
- case FALSE: /* Didn't get packet */
- spack('N', n, 0, NIL); /* Return a NAK */
- nakcnt++;
- return(state); /* Keep trying */
-
- case 'A':
- return('A'); /* user abort */
-
- default:
- msgall(KRPROERR,MSGPROER);
- return ('A'); /* Some other packet, "abort" */
- }
- }
-
- /*
- * r d a t a
- *
- * Receive Data
- */
-
- char rdata()
- {
- int num, len; /* Packet number, length */
-
- if (numtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER); return('A');};
-
- switch (rpack(&len, &num, packet)) { /* Get packet */
- case 'D': /* Got Data packet */
- if (num != n) { /* Right packet? */
- /* No! */
- if (num != ((n==0) ? 63:n-1)) /* not prev. packet */
- {msgall(KRPROERR,MSGPROER);
- return('A');
- };
- if (oldtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER);
- return('A');
- };
- spack('Y', num, 0, NIL); /* Yes, re-ACK it */
- nakcnt++;
- numtry = 0; /* Reset try counter */
- return(state); /* Don't write data! */
- }
- /* Got data with right packet number */
- #ifdef nooverlap
- /* Cannot handle concurrent disk and serial i/o, so delay ACK */
- /* until file written */
- bufemp(packet, len); /* Write the data to the file */
- spack('Y', n, 0, NIL); /* Acknowledge the packet */
- #else
- /* ACK before file write to overlap disk and serial i/o */
- spack('Y', n, 0, NIL); /* Acknowledge the packet */
- bufemp(packet, len); /* Write the data to the file */
- #endif
- oldtry = numtry; /* Reset the try counters */
- numtry = 0; /* ... */
- n = (n + 1) % 64; /* Bump packet number, mod 64 */
- n_total++;
- if (ferror(fp))
- {msgall(KRFATFER,MSGFATFE);
- return('A');
- };
- return('D'); /* Remain in data state */
-
- case 'F': /* Got a File Header */
- if (num != ((n==0) ? 63:n-1)) /* not prev. packet */
- {msgall(KRPROERR,MSGPROER);
- return('A');
- };
- if (oldtry++ > maxtry)
- {msgall(KRTRAERR,MSGTRAER);
- return('A');
- };
- spack('Y', num, 0, NIL); /* ACK it again */
- nakcnt++;
- numtry = 0; /* Reset try counter */
- return(state); /* Stay in Data state */
-
- case 'Z': /* End-Of-File */
- if (num != n)
- {msgall(KRPROERR,MSGPROER);
- return('A'); /* Must have right packet number */
- };
- if (ferror(fp))
- {msgall(KRFATFER,MSGFATFE);
- return('A');
- };
- #ifdef nooverlap
- /* can't handle disk and serial i/o at the same time */
- fclose(fp); /* close the file */
- spack('Y', n, 0, NIL); /* Ack the 'Z' packet */
- #else
- /* ACK before close to allow i/o overlap */
- spack('Y', n, 0, NIL); /* OK, ACK it. */
- fclose(fp); /* Close the file */
- #endif
- n = (n + 1) % 64; /* Bump packet number */
- msgall(-1,MSGTREOF,filnam);
- n_total++;
- filecnt++;
- dt_files(TRUE);
- filnam[0] = '\0';
- return('F'); /* Go back to Receive File state */
-
- case 'E': /* Error packet received */
- prerrpkt(packet); /* Print it out and */
- return('E'); /* abort */
-
- case FALSE: /* Didn't get packet */
- spack('N', n, 0, NIL); /* Return a NAK */
- nakcnt++;
- return(state); /* Keep trying */
-
- case 'A':
- return('A'); /* user abort */
-
- default:
- msgall(KRPROERR,MSGPROER);
- return('A'); /* Some other packet, "abort" */
- }
- }